import os
import time
from multiprocessing import Process,Pool,Queue,Manager,Pipe,Lock

def run_proc(name,age,**kwargs):
    for i in range(10):
        print('子进程运行中，name= %s,age=%d ,pid=%d...' % (name,age,os.getpid()))
        print(kwargs)
        time.sleep(0.2)

def producer(queue):
    queue.put('a')
    time.sleep(2)

def consumer(queue):
    time.sleep(2)
    data = queue.get()
    print(data)


if __name__=='__main__':
    print('父进程 %d.' % os.getpid())
    p = Process(target=run_proc, args=('test',18),kwargs={"m":20}) # 创建子进程，传入参数
    print('子进程将要执行')
    p.start() # 启动子进程
    p.join() # 等待子进程结束后再继续往下运行，通常用于进程间的同步
    print('子进程结束')
    # 进程池
    pool = Pool(3) # 创建进程池，最大进程数为3
    for i in range(5):
        # print("----%d---"%i)
        pool.apply_async(run_proc, args=('test',18),kwargs={"m":20}) # 向进程池中添加任务，非阻塞
    print('----start----')  # 主进程不会等待进程池中的任务执行完毕再结束
    pool.close() # 关闭进程池，不再接受新的任务
    pool.join() # 主进程阻塞等待子进程的退出，join方法要在close或terminate之后使用
    print('----end----')    # 主进程结束
    # 进程间通信
    # Queue
    queue = Queue(3) # 创建消息队列，最多可接收3条消息
    p1 = Process(target=producer, args=(queue,)) # 创建生产者进程，向队列中添加消息
    p2 = Process(target=consumer, args=(queue,)) # 创建消费者进程，从队列中获取消息
    p1.start() # 启动生产者进程
    p2.start() # 启动消费者进程
    p1.join() # 等待生产者进程结束
    p2.terminate() # 终止消费者进程
    # Pipe
    pipe = Pipe() # 创建管道
    p1 = Process(target=producer, args=(pipe[0],)) # 创建生产者进程，向管道中添加消息
    p2 = Process(target=consumer, args=(pipe[1],)) # 创建消费者进程，从管道中获取消息
    p1.start() # 启动生产者进程
    p2.start() # 启动消费者进程
    p1.join() # 等待生产者进程结束
    p2.terminate() # 终止消费者进程
    # Manager
    manager = Manager() # 创建管理器对象
    queue = manager.Queue() # 创建消息队列
    p1 = Process(target=producer, args=(queue,)) # 创建生产者进程，向队列中添加消息
    p2 = Process(target=consumer, args=(queue,)) # 创建消费者进程，从队列中获取消息
    p1.start() # 启动生产者进程
    p2.start() # 启动消费者进程
    p1.join() # 等待生产者进程结束
    p2.terminate() # 终止消费者进程
    # Lock
    lock = Lock() # 创建锁对象
    p1 = Process(target=run_proc, args=('test',18),kwargs={"m":20},lock=lock) # 创建子进程，传入参数和锁对象    # 启动子进程
    p2 = Process(target=run_proc, args=('test',18),kwargs={"m":20},lock=lock) # 创建子进程，传入参数和锁对象    # 启动子进程
    p1.start() # 启动子进程
    p2.start() # 启动子进程
    p1.join() # 等待子进程结束
    p2.join() # 等待子进程结束
    print('子进程结束')
    # 进程间共享数据
    # Manager
    manager = Manager() # 创建管理器对象
    dict1 = manager.dict() # 创建字典
    p = Process(target=run_proc, args=('test',18),kwargs={"m":20},dict=dict1) # 创建子进程，传入参数和字典对象    # 启动子进程
    p.start() # 启动子进程
    p.join() # 等待子进程结束
    print(dict1) # 打印字典
    # Pipe
    pipe = Pipe() # 创建管道
    p = Process(target=run_proc, args=('test',18),kwargs={"m":20},pipe=pipe) # 创建子进程，传入参数和管道对象    # 启动子进程
    p.start() # 启动子进程
    p.join() # 等待子进程结束
    print(pipe[0].recv()) # 从管道中获取数据
    print('子进程结束')